//2.装饰器模式典型应用之装饰器
//2.1类装饰器（普通装饰器）
export { }
interface Animal{
  swings: number;
  fly(): void;
}
//在类装饰器中target是该类的构造函数
function flyable(target:any) {
  target.prototype.swings = 2;
  target.prototype.fly = function () {
    console.log('会飞的方法fly');
  }
}
//普通装饰器
@flyable
class  Animal {
  constructor() {}
};
let animal = new Animal();
animal.fly();
console.log(animal.swings)


//2.2 类装饰器（装饰器工厂）
interface Animal2{
  swings: number;
  fly(): void;
}
//在类装饰器中target是该类的构造函数
function flyable2(swings:number) {
  return function (target: any) {
            target.prototype.swings = swings;
            target.prototype.fly = function () {
              console.log('会飞的方法fly222');
            }
  }
  
}
//装饰器工厂
@flyable2(5)
class  Animal2 {
  constructor() {}
};
let animal2 = new Animal2();
animal2.fly();
console.log(animal2.swings)


//2.3 属性装饰器、方法装饰器
//属性装饰器
//实例属性时，target是类的原型对象，key是属性名字
function instancePropertyDecorator(target:any,key:any) {
  target.protoName = '我是原型上的属性';
  console.log('instancePropertyDecorator=>', target, key);
}
//静态属性时，target是类的构造函数，key是属性名字
function classPropertyDecorator(target:any,key:any) {
  console.log('classPropertyDecorator=>', target, key);
}
//方法装饰器
//实例属性时，target是类的原型对象，key是属性名字，descriptor是属性描述符
function instanceMethodDecorator(target:any,key:any,descriptor:any) {
   console.log('instanceMethodDecorator=>', target, key,descriptor);
}
//静态属性时，target是类的原型对象，key是属性名字，descriptor是属性描述符
function classMethodDecorator(target:any,key:any,descriptor:any) {
  console.log('classMethodDecorator=>', target, key,descriptor);
}
class Person{
  @instancePropertyDecorator
  instanceProperty: string;//实例属性
  @classPropertyDecorator
  static classProperty: string;//静态属性
  constructor() {
    this.instanceProperty ='111'
  }
  @instanceMethodDecorator
  instanceMethod() {//实例方法
    
  };
  @classMethodDecorator
  static classMethod() {//静态方法
    
  }
}